using Gameplay.PVE.Config;
using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;

namespace Gameplay.PVE.Skill
{
    public class TrackRocket : SkillBullet
    {
        private UnitBase target;
        private Transform trackingPoint;
        private bool isDamaged = false;

        private Vector3 direction;
        
        private float acceleratePercent = 0;
        private float angleAccelerateAPercent = 0;
        private float speedUpTime = 3;
        private float angleSpeedUpTime = 1f;
        private float startSpeedUpTime = 0;

        private float time;

        private int bulletIndex;

        private Vector3 targetOffset;
        
        public void SetTargetAndIndex(UnitBase target,int bulletIndex)
        {
            this.bulletIndex = bulletIndex;
            if (target == null)
            {
                //Debug.LogError("targetIsNul");
                return;
            }
            this.target = target;
            var list = target.Data.hitPoints;
            if (list.Count == 0)
            {
                return;
            }
            var index = Random.Range(0, list.Count);
            /*isHeadShot = false;
            if (index == 0 && Random.Range(0,100) < 10)
            {
                isHeadShot = true;
            }*/

            isDamaged = false;
            trackingPoint = list[index];
        }
        
        public override void Initialize(PveSkillBulletConfig config, PveSkillConfig skillConfig,SkillBase skill, Vector3 startPosition, Vector3 offset, Vector3 angle,
            UnitBase source)
        {
            base.Initialize(config, skillConfig,skill, startPosition, offset, angle, source);
            time = 0;
            if (!IsDisposed)
            {
                acceleratePercent = 0.3f;
                angleAccelerateAPercent = 0;
                //var forward = bullet.transform.forward;
                //var normal = Quaternion.AngleAxis(90, Vector3.up) * forward;
                //direction = Quaternion.AngleAxis(Random.Range(-90, 90), Vector3.up) * forward;
                //direction = Quaternion.AngleAxis(Random.Range(-30, -90), normal) * direction;
                //angle += PveUtils.GetRandomVector3(new Vector3(-20, -20, -20), new Vector3(20, 20, 20));
                
                if (target != null)
                {
                    //0.5 - 2,
                    var distance = Vector3.Distance(bullet.transform.position, target.Data.position);
                    var percent = Mathf.InverseLerp(4, 12, distance);
                    angleSpeedUpTime = Mathf.Lerp(0.2f,1.5f,percent) * Random.Range(0.8f,1.2f);
                    var xOffset = Mathf.Lerp(-5, -15,percent) * (Random.Range(0,1f)<0.5f?1:-1) * Random.Range(0.5f,1.5f);
                    var yOffset = Mathf.Lerp(10, 20,percent) * (bulletIndex % 2 == 0 ? 1 : -1) * Random.Range(0.5f,1.5f);
                    angle += new Vector3(xOffset,yOffset,0);
                    direction = (Quaternion.Euler(angle) * Vector3.forward).normalized;
                    bullet.transform.forward = direction;
                    targetOffset = new Vector3(0, Random.Range(0, 1f), 0);
                }
                
                //direction = Quaternion.Euler(angle) * Vector3.forward;
                speed = acceleratePercent * speedValue * direction;
               
            }
            
        }
        
        public override void Update(float deltaTime)
        {
            if (IsDisposed)
            {
                return;
            }
            lastTime = time;
            time += deltaTime;
            if (isDamaged)
            {
                return;
            }

            acceleratePercent = time / speedUpTime + 0.4f;
            angleAccelerateAPercent = time / angleSpeedUpTime;
            if (acceleratePercent > 1)
            {
                acceleratePercent = 1;
            }
            
            
            if (target != null)
            {
                Vector3 targetPosition = target.Data.position + targetOffset;
                var distance = Vector3.Distance(targetPosition, lastPosition);
                if (distance < 2)
                {
                    angleAccelerateAPercent = angleAccelerateAPercent * 6f;
                }
                else if (angleAccelerateAPercent > 1)
                {
                    angleAccelerateAPercent = angleAccelerateAPercent * 1.5f;
                }
                float speedValue = this.speedValue * acceleratePercent * 2;
               
                Vector3 targetDirection = targetPosition - lastPosition;
                Vector3 dirOffset = Quaternion.AngleAxis(90, Vector3.Cross(direction,targetDirection)) * direction;
                
                Vector3 newDir = (direction + deltaTime * angleAccelerateAPercent * 3 * dirOffset).normalized;
                if (Vector3.Angle(targetDirection, direction) < Vector3.Angle(direction, newDir))
                {
                    direction = targetDirection;
                }
                else
                {
                    direction = newDir;
                }


                speed = speedValue * direction.normalized;
               
                if (speed != Vector3.zero)
                {
                    bullet.transform.forward = speed;
                }

                this.targetPosition = targetPosition;
                if (target.Data.isDead && distance < 0.1f)
                {
                    bullet.transform.position = targetPosition;
                    UpdateTrailPosition(targetPosition);
                    Dispose();
                    return;
                }
                else if (distance < 0.3f)
                {
                    HitUnitRegardlessOfType(target,targetPosition);
                    UpdateTrailPosition(targetPosition);
                    Dispose();
                    return;
                }
            }
            
            //CheckHit(lastPosition, speed, speedValue * deltaTime,true);
            if (isDamaged)
            {
                return;
            }

            UpdatePosition(deltaTime);
            if (!IsDisposed && lastPosition.y <= 0)
            {
                var newPosition = new Vector3(lastPosition.x,0,lastPosition.z);
                bullet.transform.position = newPosition;
                if (target != null && Vector3.Distance(newPosition, targetPosition) < 0.3f)
                {
                    HitUnitRegardlessOfType(target,targetPosition);
                }
                UpdateTrailPosition(newPosition);
                Dispose();
                return;
            }
            UpdateTrail();
        }
        
        public override void CheckStartHit()
        {
            
        }
    }
}